﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Newtonsoft.Json.Linq;
using RayD.Core;
using RayD.Repository;
using RayD.Repository.Entites.SystemModule;
using RayD.App.SystemModule;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace RayD.WebApi.Controllers
{
    [Authorize]
    [Route("ws")]
    public class WebSocketController : BaseController
    {
        #region 构造函数注入
        private IRepository BaseRepository;
        private UserApp _User;
        public WebSocketController(IRepository repository, UserApp User)
        {
            this.BaseRepository = repository;
            this._User = User;
        }
        #endregion

        #region 参数实体
        /// <summary>
        /// 会话实体
        /// </summary>
        public class ChatModel
        {
            /// <summary>
            /// 客户端id
            /// </summary>
            public Guid id { get; set; }
            /// <summary>
            /// 名称
            /// </summary>
            public string name { get; set; }
            /// <summary>
            /// 会话类型  group / friend 
            /// </summary>
            public string type { get; set; }
            /// <summary>
            /// 是否在线
            /// </summary>
            public bool online { get; set; }
            /// <summary>
            /// 头像
            /// </summary>
            public string avatar { get; set; }
            /// <summary>
            /// 成员信息（type = group）
            /// </summary>
            public List<ChatModel> userList { get; set; }
            /// <summary>
            /// 群公告栏（type = group）
            /// </summary>
            public object[] notices { get; set; }
        }
        /// <summary>
        /// 单聊请求参数
        /// </summary>
        public class SendMsgModel
        {
            /// <summary>
            /// 发送者
            /// </summary>
            public Guid senderWebsocketId { get; set; }
            /// <summary>
            /// 接收者
            /// </summary>
            public Guid receiveWebsocketId { get; set; }
            /// <summary>
            /// 发送内容
            /// </summary>
            public string message { get; set; }
            /// <summary>
            /// 是否需要回执
            /// </summary>
            public bool isReceipt { get; set; }
        }
        /// <summary>
        /// 群聊请求参数
        /// </summary>
        public class SendChannelMsgModel
        {
            /// <summary>
            /// 发送者
            /// </summary>
            public Guid websocketId { get; set; }
            /// <summary>
            /// 消息频道
            /// </summary>
            public string channel { get; set; }
            /// <summary>
            /// 发送内容
            /// </summary>
            public string message { get; set; }
        }
        #endregion

        public string Ip => this.Request.Headers["X-Real-IP"].FirstOrDefault() ?? this.Request.HttpContext.Connection.RemoteIpAddress.ToString();

        /// <summary>
        /// 获取websocket分区
        /// </summary>
        /// <param name="websocketId">本地标识，若无则不传，接口会返回新的，请保存本地localStoregy重复使用</param>
        /// <returns></returns>
        [HttpPost("pre-connect")]
        public ResParameter<object> preConnect(Guid? websocketId)
        {
            if (websocketId == null) websocketId = new Guid(AuthenticationHelper.LoginUserInfo.userId);
            var wsserver = ImHelper.PrevConnectServer(websocketId.Value, this.Ip);
            return Success<object>(new
            {
                code = 0,
                server = wsserver,
                websocketId = websocketId
            });
        }
        /// <summary>
        /// 获取会话
        /// </summary>
        /// <param name="websocketId">客户端id</param>
        /// <returns></returns>
        [HttpGet("get-chats")]
        public ResParameter<List<ChatModel>> getChats(Guid? websocketId)
        {
            List<ChatModel> chats = new List<ChatModel>();
            if (websocketId == null) websocketId = new Guid(AuthenticationHelper.LoginUserInfo.userId);
            //获取当前客户端会话（单聊）
            //var friendChats = _User.GetList("{}").Where(c => !c.B_UserId.Equals(websocketId.ToString()))
            var friendChats = BaseRepository.FindList<UserEntity>().Where(c => !c.B_UserId.Equals(websocketId.ToString()))
                                         .Select(c => new ChatModel
                                         {
                                             id = new Guid(c.B_UserId),
                                             name = c.B_RealName,
                                             type = "friend",
                                             online = false,
                                             avatar = c.B_HeadIcon
                                         })
                                         .ToList();
            for (int i = 0; i < friendChats.Count(); i++)
            {
                var fileInfo = IOHelper.Read(friendChats[i].avatar);
                if (!fileInfo.IsEmpty())
                    friendChats[i].avatar = $"data:{ fileInfo.ContentType };base64,{ Base64Helper.FileToBase64(fileInfo.FileStream) }";

                if (ImHelper.HasOnline(friendChats[i].id))
                    friendChats[i].online = true;
            }
            chats.AddRange(friendChats);
            //获取当前客户端会话（群聊）
            chats.Insert(0, new ChatModel()
            {
                id = new Guid("da2542d4-10c6-416d-a555-bbc2aa60db23"),
                name = "群聊",
                type = "group",
                userList = friendChats,
                notices = new object[]{ }
            });
            ImHelper.JoinChan(websocketId.Value, "da2542d4-10c6-416d-a555-bbc2aa60db23");//绑定消息频道

            return Success(chats);
        }
        /// <summary>
        /// 单聊
        /// </summary>
        /// <param name="sendMsgModel">单聊请求参数</param>
        /// <returns></returns>
        [HttpPost("send-msg")]
        public ResParameter<object> sendmsg(SendMsgModel sendMsgModel)
        {
            //var loginUser = 发送者;
            //var recieveUser = User.Get(receiveWebsocketId);

            //if (loginUser.好友 != recieveUser) throw new Exception("不是好友");

            ImHelper.SendMessage(sendMsgModel.senderWebsocketId, new[] { sendMsgModel.receiveWebsocketId }, sendMsgModel.message, sendMsgModel.isReceipt);

            //保存记录
            //CacheHelper.LocalCache.SetCache($"{AppSettings.ProjectName.EName}_IMChatHistory", sendMsgModel.message);

            return Success<object>(new
            {
                code = 0
            });
        }
        /// <summary>
        /// 群聊，发送频道消息，绑定频道的所有人将收到消息
        /// </summary>
        /// <param name="sendChannelMsgModel">群聊请求参数</param>
        /// <returns></returns>
        [HttpPost("send-channelmsg")]
        public object sendChannelmsg(SendChannelMsgModel sendChannelMsgModel)
        {
            ImHelper.SendChanMessage(sendChannelMsgModel.websocketId, sendChannelMsgModel.channel, sendChannelMsgModel.message);
            return Success<object>(new
            {
                code = 0
            });
        }

        ///// <summary>
        ///// 群聊，获取群列表
        ///// </summary>
        ///// <returns></returns>
        //[HttpPost("get-channels")]
        //public object getChannels()
        //{
        //    return new
        //    {
        //        code = 0,
        //        channels = ImHelper.GetChanList().Select(a => new { a.chan, a.online })
        //    };
        //}

        ///// <summary>
        ///// 群聊，绑定消息频道
        ///// </summary>
        ///// <param name="websocketId">本地标识，若无则不传，接口会返回，请保存本地重复使用</param>
        ///// <param name="channel">消息频道</param>
        ///// <returns></returns>
        //[HttpPost("subscr-channel")]
        //public object subscrChannel([FromForm] Guid websocketId, [FromForm] string channel)
        //{
        //    ImHelper.JoinChan(websocketId, channel);
        //    return new
        //    {
        //        code = 0
        //    };
        //}
    }
}
